// ignore_for_file: unrelated_type_equality_checks

import 'dart:convert';

import 'package:bruno/bruno.dart';
import 'package:dart_date/dart_date.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:yt_devops/components/gaps.dart';
import 'package:yt_devops/components/log_utils.dart';
import 'package:yt_devops/configs.dart';
import 'package:yt_devops/model/data_type_config.dart';

import 'package:yt_devops/model/device_obj/properties_model.dart';
import 'package:yt_devops/model/device_obj/spec/arrays_spec.dart';
import 'package:yt_devops/model/device_obj/spec/double_spec.dart';
import 'package:yt_devops/resources/resources.dart';
import 'package:yt_devops/resources/str_res_keys.dart';
import 'package:yt_devops/services/user/user_services.dart';
import 'package:yt_devops/styles/styles.dart';
import 'package:yt_devops/user_entity_manager.dart';
import 'package:yt_devops/utils/constants/permission_page_constant.dart';
import 'package:yt_devops/utils/constants/time_formated.dart';
import 'package:yt_devops/utils/enums.dart';
import 'package:yt_devops/utils/extensions.dart';

class FuncUtils {
  static bool isEmpty(value) {
    if (value == null) {
      return true;
    } else if (value is String) {
      return value.isEmpty;
    } else if (value is Map) {
      return value.isEmpty;
    } else if (value is Set) {
      return value.isEmpty;
    } else if (value is List) {
      return value.isEmpty;
    }
    return false;
  }

  static bool isListEmpty(List? list) {
    if (list == null) {
      return true;
    } else {
      return list.isEmpty;
    }
  }

  /// 告警类型图标
  String judgeAlarmIcon(AlarmStatusGradeType? value) {
    if (value == AlarmStatusGradeType.error) {
      return ImageAssets.errorAlarm;
    } else if (value == AlarmStatusGradeType.alarm) {
      return ImageAssets.alarmAlarm;
    } else if (value == AlarmStatusGradeType.warn) {
      return ImageAssets.warnAlarm;
    } else {
      return ImageAssets.infoAlarm;
    }
  }

  /// Color 转为 Hex字符串
  static String corlorToRgba(Color color) {
    int red = color.red, green = color.green, blue = color.blue;

    return 'rgb($red, $green, $blue)';
  }

  /// 将 json 转为 数组
  static List parseToArray(dynamic value) {
    if (value is List) {
      return value;
    }
    var result;
    try {
      result = jsonDecode(value + '');
      if (result is! List) {
        result = [];
      }
    } catch (e) {
      result = [];
    }
    return result;
  }

  /// 将物模型转为对应的值
  static formatModelValue(value, DataTypeConfig? model,
      {bool isShowUnit = true, defaultValue = '--'}) {
    dynamic specs;
    if (value == null) {
      return defaultValue;
    }
    if (model == null) {
      return value ?? defaultValue;
    }
    specs = model.specs;
    dynamic result = value;
    switch (model.type) {
      case DataTypeConfigEnum.int:
      case DataTypeConfigEnum.long:
      case DataTypeConfigEnum.double:

        ///如果value=='--' 则不显示单位
        result = value == '--'
            ? '--'
            : '$value ${isShowUnit ? ((model.specs as DoubleSpec).unit ?? '') : ''}';
        break;
      case DataTypeConfigEnum.boolean:
      case DataTypeConfigEnum.enumType:
        result = specs[value.toString()];
        break;
      case DataTypeConfigEnum.string:
        result = value;
        break;
      case DataTypeConfigEnum.bigString:
        result = value;
        break;
      case DataTypeConfigEnum.timestamp:
        result = DateTime.fromMillisecondsSinceEpoch(value)
            .format(TimeFormated.dateTimeFromated);
        break;
      case DataTypeConfigEnum.struct:
        try {
          List<PropertiesModel> list = model.specs as List<PropertiesModel>;
          '--';
          if (value is Map) {
            result = list.map((e) {
              return formatModelValue(value[e.id], e.dataType);
            });
          } else {
            result = '--';
          }
        } catch (e) {
          result = value;
        }
        break;

      case DataTypeConfigEnum.array:
        var arraySpec = specs as ArraysSpec;
        List arr = [];
        try {
          arr = parseToArray(value).mapIndexed((e, i) {
            var itemValue = '--';
            if (e != null) {
              itemValue =
                  formatModelValue(e, arraySpec.item!, defaultValue: '--');
            }
            if (specs?.aliseRule != null) {
              return '${arraySpec.aliseRule!.replaceAll('\$array.{index+1}', '$i + 1')}：$itemValue';
            } else {
              return itemValue;
            }
          }).toList();
        } catch (e) {
          arr = [value];
        }
        result = arr.join(',');

        break;
      case DataTypeConfigEnum.string:
      default:
        result = value;
        break;
    }
    return result ?? defaultValue;
  }

  static String getValueWithUnit(value, String unit) {
    return isEmpty(value?.toString()) ? '' : value.toString() + unit;
  }

  static List strToArray(String? value) {
    List result = [];
    if (value != null) {
      try {
        result = jsonDecode(value);
      } catch (e) {
        result = [value];
      }
    }
    return result;
  }

  static Map strToMap(String? value) {
    Map result = {};
    if (value != null) {
      try {
        result = jsonDecode(value);
      } catch (e) {}
    }
    return result;
  }

  static double calculateTextHeight(BuildContext context, String value,
      FontWeight fontWeight, fontSize, double maxWidth, int maxLines) {
    if (value.isEmpty) {
      return 0.0;
    }

    TextPainter painter = TextPainter(
      locale: Localizations.localeOf(context),
      maxLines: maxLines,
      textDirection: TextDirection.ltr,
      text: TextSpan(
        text: value,
        style: TextStyle(
          fontSize: fontSize,
          fontWeight: fontWeight,
        ),
      ),
    );

    painter.layout(maxWidth: maxWidth);

    return painter.width;
  }

  /// 请求提示框弹出
  static Future<void> requestTipsDislog(context, String? message, bool? success,
      {Color backgroundColor = const Color(0xFF393939),
      Duration? duration}) async {
    showDialog<void>(
      context: context,
      barrierDismissible: true,
      barrierColor: Colors.transparent,
      builder: (BuildContext dialogContext) {
        return BrnDialog(
          showIcon: true,
          messageText: message!,
          iconImage: success!
              ? Image.asset(ImageAssets.apiExecuteSuccess)
              : Image.asset(ImageAssets.apiExecuteFailure),
          themeData: BrnDialogConfig(
            contentPaddingSm: EdgeInsets.fromLTRB(0, 8.h, 0, 10.h),
            contentPaddingLg: EdgeInsets.fromLTRB(0, 8.h, 0, 10.h),
            backgroundColor: const Color(0xFF393939),
            dialogWidth: 140.w,
            bottomHeight: 140.h,
            contentTextStyle: BrnTextStyle(
              color: const Color(0xFFFFFFFF),
              fontSize: 16.sp,
            ),
          ),
        );
      },
    );
    if (duration != null) {
      await Future.delayed(
        duration,
        () => Get.back(),
      );
    }
  }

  /// 请求提示框弹出
  static Future<void> noPermissionDialog(
      {Color backgroundColor = const Color(0xFF393939),
      Duration duration = const Duration(seconds: 2)}) async {
    showDialog<void>(
      context: Get.context!,
      barrierDismissible: true,
      barrierColor: Colors.transparent,
      builder: (BuildContext dialogContext) {
        return BrnDialog(
          showIcon: true,
          messageText: ResKey.noAccessPermission.tr,
          iconImage: Image.asset('assets/images/no_permission_alarm.png'),
          themeData: BrnDialogConfig(
            contentPaddingSm: EdgeInsets.fromLTRB(0, 8.h, 0, 10.h),
            contentPaddingLg: EdgeInsets.fromLTRB(0, 8.h, 0, 10.h),
            backgroundColor: const Color(0xFF393939),
            dialogWidth: 140.w,
            bottomHeight: 140.h,
            contentTextStyle: BrnTextStyle(
              color: const Color(0xFFFFFFFF),
              fontSize: 16.sp,
            ),
          ),
        );
      },
    );
    if (duration != null) {
      await Future.delayed(
        duration,
        () => Get.back(),
      );
    }
  }

  ///
  /// 鉴权
  /// 可传入一个字符串也可以通过列表出传入
  /// [mode] 判断方式
  /// [AuthorityModeType.within] 只要有一个符合，则返回true
  /// [AuthorityModeType.include] 全部符合，则返回true
  ///[AuthorityModeType.exclude] 全部都不符合，则返回true
  /// 返回两个参数, [pass] bool 类型 ，为鉴权结果 ， [authorityPassMap] 是 Map<String,bool> 则为 每个权限对应的是否通过的结果
  ////

  static Map authentication(
      {String? authority,
      List<String>? authorityList,
      AuthorityModeType? mode = AuthorityModeType.within,
      List<String>? permissionSource}) {
    List<String> auths = [];

    if (authority != null) {
      auths.add(authority);
    }
    if (authorityList != null) {
      auths.addAll(authorityList);
    }

    bool pass = false;
    Map<String, bool> authorityPassMap = {};
    List<String> userPermission =
        permissionSource ?? UserEntityManager().permission;
    if (userPermission.contains('*:*:*') || auths.isEmpty) {
      pass = mode != AuthorityModeType.exclude;
      for (var element in auths) {
        authorityPassMap.putIfAbsent(
            element, () => mode != AuthorityModeType.exclude);
      }
    } else {
      for (var item in auths) {
        {
          switch (mode) {
            case AuthorityModeType.within:
            case AuthorityModeType.include:
              authorityPassMap.putIfAbsent(
                  item, () => userPermission.contains(item));
              break;
            case AuthorityModeType.exclude:
              authorityPassMap.putIfAbsent(
                  item, () => !userPermission.contains(item));
              break;
            default:
          }
        }
      }

      switch (mode) {
        case AuthorityModeType.within:
          pass = authorityPassMap.values.contains(true);
          break;
        case AuthorityModeType.include:
        case AuthorityModeType.exclude:
          pass = !authorityPassMap.values.contains(false);
          break;
        default:
      }
    }
    return {
      'pass': pass,
      'authorityPassMap': authorityPassMap,
    };
  }

  /// 检查是否通过授权。
  ///
  /// 该函数会根据提供的权限列表和类型，判断是否通过了指定的授权检查。
  /// 默认情况下，检查的是权限详情（'detail'）类型。
  ///
  /// @param authorities 可选参数，权限列表。如果为空，则直接返回 true。
  /// @param authorityType 可选参数，指定的权限类型，默认为 'detail'。
  /// @return 返回一个布尔值，如果通过授权检查，返回 true；否则返回 false。
  static bool isPassTargetAuthority(List? authorities,
      {AuthorityModeType? mode = AuthorityModeType.within,
      String targetAuthorityType = 'detail',
      List<String>? permissionSource}) {
    // 如果权限列表为空，则直接返回 true
    if (authorities == null || authorities.isEmpty) return true;
    List<String> detailAuthorities = [];
    // 遍历权限列表，收集指定类型的权限

    for (var item in authorities) {
      if ((item is Map) && item[targetAuthorityType] != null) {
        detailAuthorities.add(item[targetAuthorityType]);
      }
    }
    // 基于收集到的权限，调用 FuncUtils 的 authentication 方法进行授权检查
    var map = FuncUtils.authentication(
        authorityList: detailAuthorities,
        mode: mode,
        permissionSource: permissionSource);
    // 如果收集到的权限为空，或者授权检查通过，则返回 true
    if (FuncUtils.isListEmpty(detailAuthorities) || map['pass']) {
      return true;
    } else {
      return false;
    }
  }

  ///
  /// 从树结构收集指定参数对应的值
  /// [tree]原数据数组
  /// [getKey] 获取对应key的方法
  /// [getChildren] 获取对应下级的方法
  ///
  static List<K> getPropFromTree<T, K>(List<T> tree,
      {required K? Function(
        T,
      ) getKey,
      required List<T>? Function(
        T,
      ) getChildren}) {
    List<K> value = [];
    for (var item in tree) {
      var prop = getKey(item);
      if (prop != null) {
        value.add(prop);
      }
      List<T>? children = getChildren(item);
      if (children != null && children.isNotEmpty) {
        var list =
            getPropFromTree(children, getKey: getKey, getChildren: getChildren);
        value.addAll(list);
      }
    }
    return value;
  }

  /// 全局切换语言
  /// 可以选择用locale传入， 或者传入字符串格式的 lang “zh-CN”,
  ///
  static Future changeLocale(
      {Locale locale = const Locale('zh', 'CN'), String? lang}) async {
    Locale localeModel;
    if (!isEmpty(lang)) {
      var arr = lang!.split('-');
      localeModel = Locale(arr[0], arr[1]);
    } else {
      localeModel = locale;
    }
    Configs().setLocale(localeModel);

    await Get.updateLocale(localeModel);
    Log.d('切换语言==' + Get.locale.toString());
  }

  static PopupMenuItem getAppBarPopItem(Widget icon, String title, value) {
    return PopupMenuItem(
      value: value,
      enabled: false,
      child: Row(
        children: [
          icon,
          Gaps.hGap10,
          Text(
            title,
            style: TextStyles.f14,
          ),
        ],
      ),
    );
  }

  /// 设置系统默认语言
  static Locale getDefaultSystemLanguage() {
    // var languageCode = Get.deviceLocale?.languageCode ?? 'zh';
    String? languageCode = GetStorage().read(
      'changeLocale',
    );
    Locale locale = Locale(Get.deviceLocale?.languageCode ?? 'zh',
        Get.deviceLocale?.countryCode ?? 'CN');
    if (languageCode != null && languageCode.isNotEmpty) {
      if (languageCode != null && languageCode.toString() == 'en') {
        locale = const Locale('en', 'US');
      } else {
        locale = const Locale('zh', 'CN');
      }
    }
    return locale;
  }

  /// 根据语言选择宽度
  static double getWidthByLocal(double zhWidth, double enWidth) {
    return Get.locale?.languageCode == 'en' ? enWidth : zhWidth;
  }

  /// 当前系统是否是中文
  static bool iszhCN() {
    return Get.locale?.languageCode == 'zh';
  }

  ///
  /// 判断该权限列表是否通过
  /// [authorities] 可以是 List<String> 或者是 List<Map>
  ///
  static bool isPassAuthority(List? authorities,
      {List<String>? permissionSource,
      AuthorityType? authorityType,
      AuthorityModeType? mode = AuthorityModeType.within}) {
    if (authorities == null) return true;
    List<String> authorityList = [];
    for (var item in authorities) {
      if (item is String) {
        authorityList.add(item);
      } else if (item is Map && authorityType == null) {
        authorityList.addAll(item.values.toList() as List<String>);
      } else if (item is Map && item[authorityType!.name] != null) {
        authorityList.add(item[authorityType]);
      }
    }

    var map = FuncUtils.authentication(
        authorityList: authorityList,
        mode: mode,
        permissionSource: permissionSource);
    if (FuncUtils.isListEmpty(authorities) || map['pass']) {
      return true;
    } else {
      return false;
    }
  }

  ///是否展示无权限弹窗,如果是则展示弹窗
  static bool isShowNoPermissionWidget(
    List? authorities,
  ) {
    bool isShowNoPermission = false;
    isShowNoPermission = !FuncUtils.isPassAuthority(authorities);

    ///不包含这个权限 需要展示弹窗
    if (isShowNoPermission) {
      FuncUtils.noPermissionDialog();
      return isShowNoPermission;
    }
    {
      return false;
    }
  }

  static String formatMessage({
    required String resKey,
    required String defaultMessage,
  }) {
    return resKey.tr;
  }
}
